package com.exam.stu.role.business;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONArray;
import com.exam.base.business.AbstractBusiness;
import com.exam.base.model.ResponsePageModel;
import com.exam.base.service.IAbstractService;
import com.exam.base.util.ServletBeanTools;
import com.exam.stu.power.enums.PowerEnum;
import com.exam.stu.power.model.TbBtn;
import com.exam.stu.power.model.TbMenu;
import com.exam.stu.power.model.vo.RolePowerDataVo;
import com.exam.stu.power.model.vo.ZkTreeNode;
import com.exam.stu.power.service.TbBtnService;
import com.exam.stu.power.service.TbMenuService;
import com.exam.stu.role.model.TbRole;
import com.exam.stu.role.model.TbRoleMenu;
import com.exam.stu.role.service.TbRoleMenuService;
import com.exam.stu.role.service.TbRoleService;

/**
 * 角色菜单业务管理
 * @author Administrator
 *
 */
@Service("roleMenuBussiness")
public class RoleMenuBussiness extends AbstractBusiness<TbRole> {

	@Autowired
	private TbRoleService tbRoleService;
	
	@Autowired
	private TbMenuService tbMenuService;
	
	@Autowired
	private TbBtnService tbBtnService;
	
	@Autowired
	private TbRoleMenuService tbRoleMenuService;
	
	@Override
	protected IAbstractService<TbRole> getBaseService() { 
		return tbRoleService;
	}

	/**
	 * 查询分页
	 * @param request
	 * @return
	 */
	public ResponsePageModel<TbRole> getRolePageData(HttpServletRequest request) {
		try {

			TbRole queryModel = ServletBeanTools
					.populate(TbRole.class, request); 
			return this.getPageData(queryModel);

		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 添加角色
	 * @param addModel
	 * @throws Exception
	 */
	public void addRole(TbRole addModel) throws Exception { 
		TbRole queryModel = new TbRole();
		queryModel.setRoleCode(addModel.getRoleCode());
		int count = tbRoleService.queryCount(queryModel);
		
		if (count > 0)
		{
			throw new Exception("角色编码重复！");
		}
		
		tbRoleService.add(addModel);
	}
    
	/**
	 * 更新角色
	 * @param updateRole
	 * @throws Exception
	 */
	public void updateRole(TbRole updateRole) throws Exception {
		TbRole queryModel = new TbRole();
		queryModel.setRoleCode(updateRole.getRoleCode());
		List<TbRole> lstRole = tbRoleService.queryList(queryModel);

		for (TbRole tbRole : lstRole) {
			if (tbRole.getRoleCode().equals(updateRole.getRoleCode())
					&& !tbRole.getId().equals(updateRole.getId())) {
				throw new Exception("角色编码重复！");
			}
		}
		tbRoleService.update(updateRole);
	}

	/**
	 * 获取角色权限
	 * @param request
	 * @return
	 */
	public String getRolePowerJsonData(HttpServletRequest request) {
		 
		// 获取所有的菜单 与 按钮 构建菜单树
		List<TbMenu> lstMenu = tbMenuService.queryList(new TbMenu()); 
		List<TbBtn> lstBtn = tbBtnService.queryList(new TbBtn());
		
		Map<String,List<TbBtn>> btnMap = new HashMap<String, List<TbBtn>>();
		
		for (TbBtn tbBtn : lstBtn) {
			if (!btnMap.containsKey(tbBtn.getMenuId()))
			{
				btnMap.put(tbBtn.getMenuId(), new ArrayList<TbBtn>());
			}
			btnMap.get(tbBtn.getMenuId()).add(tbBtn);
		}
		
		String roleId = request.getParameter("roleId");
		// 将当前角色已有的菜单权限选上
		if (!StringUtils.isEmpty(roleId))
		{
			TbRoleMenu queryModel = new TbRoleMenu();
			queryModel.setRoleId(roleId);
			List<TbRoleMenu> lstRoleMenu = tbRoleMenuService.queryList(queryModel);
			
			for (TbRoleMenu tbRoleMenu : lstRoleMenu) {
				for (TbMenu tbMenu : lstMenu) {
					if (!tbRoleMenu.getMenuId().equals(tbMenu.getId()))
					{
						continue;
					}
					tbMenu.setChecked(true);
					if (!btnMap.containsKey(tbMenu.getId()))
					{
						continue;
					}
					String[] btnIdArray = tbRoleMenu.getBtnId().split(",");
					for (String btnId : btnIdArray) {
						for (TbBtn tbBtn : btnMap.get(tbMenu.getId())) {
							if (!tbBtn.getId().equals(btnId))
							{
								continue;
							}
							tbBtn.setChecked(true);
						}
					}
				}
			}
		}
		 
		TbMenu rootMenu = null;
		for (TbMenu tbMenu : lstMenu) {
			if (StringUtils.isEmpty(tbMenu.getParentId()))
			{
				rootMenu = tbMenu;
				break;
			}
		}
        
		 if (rootMenu != null)
		 {
			 ZkTreeNode rootNode = new ZkTreeNode();
			 rootNode.setChildren(new ArrayList<ZkTreeNode>());
			 rootNode.setText("根目录");
			 rootNode.setType(PowerEnum.ROOT.name());
			 rootNode.setId(rootMenu.getId());
			 rootNode.setParentId("");
			 
			 generateTree(rootNode,lstMenu,btnMap);
			 
			 List<ZkTreeNode> lstNode = new ArrayList<ZkTreeNode>();
				lstNode.add(rootNode);
				return JSONArray.toJSONString(lstNode); 
		 }
		
		return "";
		   
	}
	
	/**
	 * 递归构建树
	 * @param rootNot
	 * @param lstMenu
	 * @param btnMap
	 */
	private void generateTree(ZkTreeNode rootNot,List<TbMenu> lstMenu,Map<String,List<TbBtn>> btnMap)
	{
		for (TbMenu tbMenu : lstMenu) {
			if (StringUtils.isEmpty(tbMenu.getParentId()))
			{
				continue;
			}
			if (!tbMenu.getParentId().equals(rootNot.getId()))
			{
				continue;
			}
			ZkTreeNode node = new ZkTreeNode();
			node.setId(tbMenu.getId());
			node.setCode(tbMenu.getMenuCode());
			node.setText(tbMenu.getMenuName());
			node.setType(PowerEnum.MENU.name());
			node.setChildren(new ArrayList<ZkTreeNode>());
			node.setParentId(rootNot.getId());
			node.setChecked(tbMenu.isChecked());
			generateTree(node,lstMenu,btnMap);
			rootNot.getChildren().add(node);
			if (!btnMap.containsKey(node.getId()))
			{
				continue;
			}
			
			for (TbBtn tbBtn : btnMap.get(node.getId())) {
				ZkTreeNode btnNode = new ZkTreeNode();
				btnNode.setId(tbBtn.getId());
				btnNode.setCode(tbBtn.getBtnCode());
				btnNode.setText(tbBtn.getBtnName());
				btnNode.setType(PowerEnum.BTN.name());
				btnNode.setParentId(node.getId());
				btnNode.setChecked(tbBtn.isChecked());
				node.getChildren().add(btnNode);
			} 
		}
	}

	/**
	 * 更新角色菜单数据
	 * @param data
	 */
	public void updateRoleMenu(RolePowerDataVo data) {
		// 删除角色菜单数据
		TbRoleMenu deleteModel = new TbRoleMenu();
		deleteModel.setRoleId(data.getRoleId()); 
		tbRoleMenuService.delete(deleteModel);
		
		// 排除根目录
		TbMenu queryMenu = new TbMenu();
		List<TbMenu> lstMenuData = tbMenuService.queryList(queryMenu);
		
		if (lstMenuData.size() <= 0)
		{
			return;
		} 
		TbMenu rootMenu = null;
		for (TbMenu tbMenu : lstMenuData) {
			if (StringUtils.isEmpty(tbMenu.getParentId()))
			{
				rootMenu = tbMenu;
				break;
			}
		} 
		// 更新数据
		Map<String,String> roleMenubtnMap = new HashMap<String, String>();

		for (ZkTreeNode treeNode : data.getTreeData()) {
			if (PowerEnum.ROOT.name().equals(treeNode.getType()))
			{
				continue;
			}
			if (PowerEnum.MENU.name().equals(treeNode.getType()))
			{ 
				insertMenuMap(roleMenubtnMap, treeNode.getId(), rootMenu.getId());
			}
			if (PowerEnum.BTN.name().equals(treeNode.getType()))
			{
				insertMenuMap(roleMenubtnMap, treeNode.getParentId(), rootMenu.getId());
				
				String btnData = roleMenubtnMap.get(treeNode.getParentId());
				
				if (StringUtils.isEmpty(btnData))
				{
					roleMenubtnMap.put(treeNode.getParentId(), treeNode.getId());
				}
				else
				{
					roleMenubtnMap.put(treeNode.getParentId(), btnData + "," + treeNode.getId());
				} 
			}
		}
		
		List<TbRoleMenu> lstAddData = new ArrayList<TbRoleMenu>();
		TbRoleMenu temAdd = null;
		for (Entry<String, String> mapEntry : roleMenubtnMap.entrySet()) {
			temAdd = new TbRoleMenu();
			temAdd.setMenuId(mapEntry.getKey());
			temAdd.setRoleId(data.getRoleId());
			temAdd.setBtnId(mapEntry.getValue()); 
			lstAddData.add(temAdd);
		} 
		tbRoleMenuService.batchAdd(lstAddData); 
	}

	/**
	 * 初始化菜单Map
	 * @param roleMenubtnMap
	 * @param id
	 */
	private Map<String, String> insertMenuMap(Map<String, String> roleMenubtnMap,
			String id, String rootId) {
		if (rootId.equals(id))
		{
			return roleMenubtnMap;
		}
		if (!roleMenubtnMap.containsKey(id))
		{
			roleMenubtnMap.put(id, "");
		}
		return roleMenubtnMap;
	}
}
